package com.qf.config;

import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

/**
 * 我自定义的MQ的配置类
 * @author lixu
 */
@Component  //实例化的   MyRabbitMqConfig进入到SpringIOC容器中
@Slf4j
public class MyRabbitMqConfig implements
                                 RabbitTemplate.ConfirmCallback,
                                 RabbitTemplate.ReturnCallback {

    /**
     * ConfirmCallback : 小箱子   接口
     * ReturnCallback  : 小箱子   接口
     *
     * -----------------------------
     *
     * MyRabbitMqConfig : 中箱子  实现类 （干活的人是实现类）
     */
    //必须要实现

    //1:从SpringIOC容器获取出 RabbitTemplate
    @Autowired
    private RabbitTemplate rabbitTemplate;

    //初始化
    @PostConstruct //初始化前后   Spring那节课学习的  方法拦截器   初始化前 初始化后
    public void abc(){
        //将当前对象设置到 RabbitTemplate对象中  交换机接口
        rabbitTemplate.setConfirmCallback(this);//this:代表是当前对象
        //将当前对象设置到 RabbitTemplate对象中 队列接口
        rabbitTemplate.setReturnCallback(this);//this:代表是当前对象
    }

    /**
     * 交换机确认接口中方法
     *    成功或失败都执行下面这个方法
     * @param correlationData
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {

        //ack : 确认或应答   abbr. 命令正确应答；确认字符（acknowledgement character）
        if(ack){
            //成功确认
            //System.out.println("成功了");
            log.info("交换机接收到了消息并确认成功!");
        }else{
            //失败确认  重新发消息 （2~3 ） 打印日志 通知程序员 人工介入
            log.error("交换机接收消息确认失败:{}" ,JSONObject.toJSONString(correlationData));
            //重新发消息 逻辑开发  RabbitMQ已经不能再帮我们了
        }
    }
    /**
     * 队列确认接口中方法
     *   只有失败才会执行下面的方法
     * @param message
     */
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {

        //执行此方法 肯定是队列确认失败了  重新发消息 （2~3 ） 打印日志 通知程序员 人工介入
        log.error("队列接收消息确认失败:交换机:{},RoutingKey:{},message:{}"
                ,exchange,routingKey,JSONObject.toJSONString(message));



        //重新发消息 逻辑开发  RabbitMQ已经不能再帮我们了

    }






}
